home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcr / pcr4_4.lha / DIST / loading / simplify_symtab.c < prev    next >
C/C++ Source or Header  |  1989-04-03  |  8KB  |  308 lines

  1. /* begincopyright
  2.   Copyright (c) 1988 Xerox Corporation. All rights reserved.
  3.   Use and copying of this software and preparation of derivative works based
  4.   upon this software are permitted. Any distribution of this software or
  5.   derivative works must comply with all applicable United States export
  6.   control laws. This software is made available AS IS, and Xerox Corporation
  7.   makes no warranty about the software, its performance or its conformity to
  8.   any specification. Any person obtaining a copy of this software is requested
  9.   to send their name and post office or electronic mail address to:
  10.     PCR Coordinator
  11.     Xerox PARC
  12.     3333 Coyote Hill Rd.
  13.     Palo Alto, CA
  14.   endcopyright */
  15. #include <sys/types.h>
  16. #include <sys/file.h>
  17. #include <sys/stat.h>
  18. #include <stdio.h>
  19. #include <a.out.h>
  20. #include <errno.h>
  21.  
  22. #ifdef sparc
  23. #define r_symbolnum r_index
  24. #define relocation_info reloc_info_sparc
  25. #endif
  26.  
  27. #define CLEAN(var) {if (var) {free(var); var = 0;}}
  28.  
  29. static int file_length;/* length of input file in bytes */
  30. static FILE *file;     /* input file                    */
  31.  
  32. struct exec header;    
  33. struct nlist *symtab;
  34. caddr_t stringtab;
  35. int num_symbols;
  36. long string_len;
  37. unsigned long num_reloc_data_items, num_reloc_text_items;
  38. struct relocation_info *data_reloctab, *text_reloctab;/* relocation table */
  39. unsigned long num_reloc_data_items_kept, num_reloc_text_items_kept;
  40.  
  41. #define INCN 60000
  42. static int maxn = 0;
  43. static int nextn = 0;
  44. static int *saven = 0;
  45. #define INCSTRX 60000*8
  46. static int maxstrx = 0;
  47. static int nextstrx = sizeof(int);
  48. static caddr_t newstringtab = 0;
  49.  
  50. char *current_file;
  51.  
  52. compare_n(a, b)
  53. int *a, *b;
  54. {
  55.   return(*a - *b);
  56. }
  57.  
  58. /*
  59.  *  Main program for 'simplify_symtab'.
  60.  */
  61. main(argc, argv)
  62.      char **argv;
  63. {
  64.   
  65.   /* process arguments */
  66.   if (argc < 2) {
  67.     printf("Usage: %s  filename.\n\tRemoves any dbx type symbols (those with stabs bits on.)~~the stab ", argv[0]);
  68.     exit(1);
  69.   };
  70.   for (; --argc > 0;) {
  71.     simplify_file(*++argv);
  72.   }
  73.   exit(0);
  74. }
  75.   
  76. simplify_file(onefilename)
  77.      char *onefilename;
  78. {
  79.   int i, n_i;
  80.   caddr_t cp;
  81.  
  82.   printf("Simplifying %s.\n", onefilename);
  83.   current_file = onefilename;  /* for error messages */
  84.  
  85.   /*
  86.    *  Initialize.
  87.    */
  88.   maxn = 0;
  89.   nextn = 0;
  90.   CLEAN(saven);
  91.   CLEAN(symtab);
  92.   CLEAN(data_reloctab);
  93.   CLEAN(text_reloctab);
  94.   CLEAN(stringtab);
  95.   maxstrx = 0;
  96.   nextstrx = sizeof(int);
  97.   CLEAN(newstringtab);
  98.  
  99.   /*
  100.    *    Open the file:  don't return if unopened.
  101.    */
  102.   open_file(onefilename);
  103.  
  104.   /* 
  105.    *  Look for symbols without nstab bits set--remember them.
  106.    *  Remember the strings associated with the remembered symbols.
  107.    */
  108.   for(i=0; i < num_symbols; i++ ) {
  109.     if ( ! (symtab[i].n_type & N_STAB)) {
  110.       remember_n(i);
  111.       cp = symtab[i].n_un.n_strx + stringtab;
  112.       symtab[i].n_un.n_strx = nextstrx;
  113.       remember_string(cp);
  114.     } else {
  115.       i = i;  /* someplace to put a breakpoint */
  116.     }
  117.   }
  118.  
  119.   /*
  120.    *  Start point for writing new file information.
  121.    */
  122.   fseek(file, N_TRELOFF(header), 0);
  123.  
  124.   /*
  125.    *  Write out text relocation information, adjusted to new symbol locations.
  126.    */
  127.   num_reloc_text_items_kept = 0;
  128.   for (i=0; i < num_reloc_text_items; i++) {
  129.     if (text_reloctab[i].r_extern && (n_i = n_p(text_reloctab[i].r_symbolnum)) == -1) {
  130.       i = i;   /* a place to put breakpoints */
  131.     } else {
  132.       if (text_reloctab[i].r_extern) {
  133.     text_reloctab[i].r_symbolnum = n_i;
  134.       }
  135.       fwrite(&text_reloctab[i], sizeof(struct relocation_info), 1, file);
  136.       num_reloc_text_items_kept += 1;
  137.     }
  138.   }
  139.   /*
  140.    *  Write out data relocation information that points to saved symbols only.
  141.    */
  142.   num_reloc_data_items_kept = 0;
  143.   for (i=0; i < num_reloc_data_items; i++) {
  144.     if (data_reloctab[i].r_extern && (n_i = n_p(data_reloctab[i].r_symbolnum)) == -1) {
  145.       i = i;   /* a place to put breakpoints */
  146.     } else {
  147.       if (data_reloctab[i].r_extern) {
  148.     data_reloctab[i].r_symbolnum = n_i;
  149.       }
  150.       fwrite(&data_reloctab[i], sizeof(struct relocation_info), 1, file);
  151.       num_reloc_data_items_kept += 1;
  152.     }
  153.   }
  154.  
  155.   /* 
  156.    *  Write out symbols that did not have nstabs bit set.
  157.    *  by  copying them in place on top of other symbols.
  158.    */
  159.   for(i=0; i < nextn; i++ ) {
  160.     fwrite(&symtab[saven[i]], sizeof(struct nlist), 1, file);
  161.   }
  162.  
  163.   /*
  164.    *  Write out the same old stringtab (now in a new place in the file).
  165.    *  fwrite(stringtab, string_len, 1, file);
  166.    */
  167.  
  168.   /*
  169.    * Write new string table
  170.    */
  171.   *(int *)newstringtab = nextstrx;
  172.   fwrite(newstringtab, nextstrx, 1, file);
  173.   
  174.   /*
  175.    *  Update the header, and write it out.
  176.    */
  177.   header.a_syms = sizeof(struct nlist)*nextn;
  178.   header.a_drsize = sizeof(struct relocation_info)*num_reloc_data_items_kept;
  179.   header.a_trsize = sizeof(struct relocation_info)*num_reloc_text_items_kept;
  180.   fseek(file, (long)0, 0);
  181.   fwrite(&header, sizeof(struct exec), 1, file);
  182.  
  183.   fflush(file);
  184.   i = file_length - (num_symbols-nextn)*sizeof(struct nlist);
  185.   i -= (num_reloc_data_items - num_reloc_data_items_kept + 
  186.         num_reloc_text_items - num_reloc_text_items_kept) * sizeof(struct relocation_info);
  187.   i -= string_len - nextstrx;
  188.   ftruncate(fileno(file), i);
  189.  
  190.   /* done with this file */
  191.   fclose(file);
  192. }
  193.  
  194. open_file(filename)
  195. char *filename;
  196. {
  197.   struct stat the_stat_buffer;
  198.   /*
  199.    *    Open the file:  don't return if unopened.
  200.    */
  201.   if ((file = fopen(filename, "r+")) == NULL) {
  202.     char temp[128];
  203.     sprintf(temp, "Cannot open file '%s'.", filename);
  204.     error(temp); /* never returns */
  205.   }
  206.   
  207.   /* get the file size */
  208.   fstat(fileno(file), &the_stat_buffer);
  209.   file_length = the_stat_buffer.st_size;
  210.   
  211.   fseek(file, (long)0, 0);
  212.   fread (&header, sizeof(struct exec), 1, file);
  213.   if (N_BADMAG(header)) {
  214.     error("Bad magic number."); /* never returns */
  215.   }
  216.  
  217.   num_reloc_text_items = (header.a_trsize / sizeof (struct relocation_info));
  218.   num_reloc_data_items = (header.a_drsize / sizeof (struct relocation_info));
  219.   
  220.   if (num_reloc_text_items > 0) {
  221.     text_reloctab = (struct relocation_info *)malloc(sizeof(struct relocation_info)*num_reloc_text_items);
  222.     fseek(file, N_TRELOFF(header), 0);
  223.     fread (text_reloctab, sizeof (struct relocation_info), num_reloc_text_items, file);
  224.   }
  225.  
  226.   if (num_reloc_data_items > 0) {
  227.     data_reloctab = (struct relocation_info *)malloc(sizeof(struct relocation_info)*num_reloc_data_items);
  228.     fseek(file, N_DRELOFF(header), 0);
  229.     fread (data_reloctab, sizeof (struct relocation_info), num_reloc_data_items, file);
  230.   }
  231.  
  232.   /*
  233.    *    Read in the symbol table
  234.    */
  235.   num_symbols = header.a_syms / (sizeof (struct nlist));
  236.   if (num_symbols <= 0) {
  237.     error("No symbol table."); /* never returns */
  238.   }
  239.   symtab= (struct nlist *) malloc (header.a_syms);
  240.   fseek(file, N_SYMOFF(header), 0);
  241.   fread (symtab, sizeof (struct nlist), num_symbols, file);
  242.  
  243.   /*
  244.    *    Read in the string table
  245.    */
  246.   {
  247.     string_len = (file_length - N_STROFF(header));
  248.     if (string_len <= 0) {    
  249.       error("No string table."); /* never returns */
  250.     }
  251.     stringtab = (caddr_t) malloc (string_len);
  252.     fseek(file, N_STROFF(header), 0);
  253.     fread (stringtab, 1, string_len, file);
  254.   }
  255. }
  256.  
  257. error(s)
  258. char *s;
  259. {
  260.   printf("simplify_symtab error: %s, in file '%s'\n", s, current_file);
  261.   exit(1);
  262. }
  263.  
  264. remember_n(n)
  265. int n;
  266. {
  267.   if (nextn >= maxn) {
  268.     /* need more storage */
  269.     maxn += INCN;
  270.     if (saven) {
  271.       saven = (int *)realloc(saven, maxn*sizeof(int));
  272.     } else {
  273.       saven = (int *)malloc(maxn*sizeof(int));
  274.     }
  275.   }
  276.   saven[nextn++] = n;
  277. }
  278.  
  279. n_p(n)
  280. int n;
  281. {
  282.   int *retval;
  283.   retval = (int *)bsearch(&n, saven, nextn, sizeof(int), compare_n);
  284.   if (retval == 0) {
  285.     return -1;
  286.   } else {
  287.     return ((long)retval - (long)saven)/sizeof(int);
  288.   }
  289. }
  290.  
  291. remember_string(cp)
  292. caddr_t cp;
  293. {
  294.   int len;
  295.   
  296.   len = strlen(cp) + 1;
  297.   if (nextstrx+len >= maxstrx) {
  298.     maxstrx += INCSTRX;
  299.     if (newstringtab) {
  300.       newstringtab = (caddr_t)realloc(newstringtab, maxstrx);
  301.     } else {
  302.       newstringtab = (caddr_t)malloc(maxstrx);
  303.     }
  304.   }
  305.   strcpy(newstringtab + nextstrx, cp);
  306.   nextstrx += len;
  307. }
  308.